using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using Microsoft.Practices.CompositeUI.Commands;
using Microsoft.Practices.ObjectBuilder;
using SCSFContrib.CompositeUI.WPF.Commands;

namespace UIAdapters
{
	public partial class MainWindow : IBuilderAware
	{
		public static readonly string MenuSiteName = "Menu";
		public static readonly string QuickLinksSiteName = "QuickLinks";
		public static readonly string FileMenuSiteName = "File";
		public static readonly string FilePropertiesSiteName = "FileProperties";
		public static readonly string EditMenuSiteName = "Edit";
		public static readonly string HelpMenuSiteName = "Help";
		public static readonly string FileToolBarSiteName = "FileToolBar";
		private readonly RootWorkItem _workItem;
		private readonly MenuItem _extraPropertiesMenuItem;
		private readonly TextBlock _extraPropertiesQuickLink;

		public MainWindow([Dependency] RootWorkItem workItem)
		{
			InitializeComponent();
			_workItem = workItem;
			_extraPropertiesMenuItem = GetMenuItem("Extra Properties", null, "ExtraProperties");
			_extraPropertiesQuickLink = GetHyperlink("Show extra properties", "ExtraProperties");
		}

		public void OnBuiltUp(string id)
		{
			//I've kept things simple here. In a real app, you might like to move command definitions into an XML file or something


			//register primary UI extension sites
			_workItem.UIExtensionSites.RegisterSite(MenuSiteName, _menu);
			_workItem.UIExtensionSites.RegisterSite(QuickLinksSiteName, _quickLinks);

			//register standard top-level menus
			foreach (string siteName in new string[] {FileMenuSiteName, EditMenuSiteName, HelpMenuSiteName})
			{
				_workItem.UIExtensionSites[MenuSiteName].Add(GetMenuItem("_" + siteName, siteName, null));
			}

			//register some standard file menu items
			_workItem.UIExtensionSites[FileMenuSiteName].Add(GetMenuItem("_New", null, "New"));
			Separator separator = new Separator();
			_workItem.UIExtensionSites[FileMenuSiteName].Add(separator);
			_workItem.UIExtensionSites.RegisterSite(FilePropertiesSiteName, separator);
			_workItem.UIExtensionSites[FileMenuSiteName].Add(GetMenuItem("_Properties", null, "Properties"));
			separator = new Separator();
			_workItem.UIExtensionSites[FileMenuSiteName].Add(separator);
			_workItem.UIExtensionSites[FileMenuSiteName].Add(GetMenuItem("_Exit", null, "Exit"));

			_button.Command = new WrappedCabCommand(_workItem.Commands["Exit"]);

			//register standard toolbars
			foreach (string siteName in new string[] { FileToolBarSiteName })
			{
				ToolBar toolBar = new ToolBar();
				_toolBarTray.ToolBars.Add(toolBar);
				//register this toolbar tray as an extension point
				_workItem.UIExtensionSites.RegisterSite(siteName, toolBar);
			}

			//register standard file toolbar items
			_workItem.UIExtensionSites[FileToolBarSiteName].Add(GetToolBarItem("New", "New"));
			_workItem.UIExtensionSites[FileToolBarSiteName].Add(GetToolBarItem("Exit", "Exit"));

			//register quick links
			_workItem.UIExtensionSites[QuickLinksSiteName].Add(GetHyperlink("Create a new document", "New"));
			_workItem.UIExtensionSites[QuickLinksSiteName].Add(GetHyperlink("Exit the application", "Exit"));
		}

		[CommandHandler("New")]
		public void New(object sender, EventArgs e)
		{
			MessageBox.Show("Here's the New function.");
		}

		[CommandHandler("Properties")]
		public void Properties(object sender, EventArgs e)
		{
			MessageBox.Show("Here's the Properties function.");
		}

		[CommandHandler("ExtraProperties")]
		public void ExtraProperties(object sender, EventArgs e)
		{
			MessageBox.Show("Here's the Extra Properties function.");
		}

		[CommandHandler("Exit")]
		public void Exit(object sender, EventArgs e)
		{
			if (MessageBox.Show("I suspect that you slipped and probably don't really want to exit - are you sure you want to?", "Annoying Confirmation Question", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
			{
				Close();
			}
		}

		private MenuItem GetMenuItem(string header, string siteName, string commandName)
		{
			MenuItem menuItem = new MenuItem();
			menuItem.Header = header;

			if (siteName != null)
			{
				_workItem.UIExtensionSites.RegisterSite(siteName, menuItem);
			}

			if (commandName != null)
			{
				_workItem.Commands[commandName].AddInvoker(menuItem, "Click");
			}

			return menuItem;
		}

		private Button GetToolBarItem(string imageResourceName, string commandName)
		{
			Button button = new Button();
			Image image = new Image();
			image.Style = FindResource("ToolBarItemImageStyle") as Style;
			image.Source = FindResource(imageResourceName) as System.Windows.Media.ImageSource;
			button.Content = image;

			if (commandName != null)
			{
				_workItem.Commands[commandName].AddInvoker(button, "Click");
			}

			return button;
		}

		private TextBlock GetHyperlink(string text, string commandName)
		{
			Hyperlink hyperlink = new Hyperlink(new Run(text));
			//wrap in text block for easy styling
			TextBlock textBlock = new TextBlock(hyperlink);

			if (commandName != null)
			{
				_workItem.Commands[commandName].AddInvoker(hyperlink, "Click");
			}

			return textBlock;
		}

		private void AddPropertiesCommand(object sender, EventArgs e)
		{
			_workItem.UIExtensionSites[FilePropertiesSiteName].Add(_extraPropertiesMenuItem);
		}

		private void RemovePropertiesCommand(object sender, EventArgs e)
		{
			_workItem.UIExtensionSites[FilePropertiesSiteName].Remove(_extraPropertiesMenuItem);
		}

		private void AddPropertiesCommandToQuickLinks(object sender, EventArgs e)
		{
			_workItem.UIExtensionSites[QuickLinksSiteName].Add(_extraPropertiesQuickLink);
		}

		private void RemovePropertiesCommandFromQuickLinks(object sender, EventArgs e)
		{
			_workItem.UIExtensionSites[QuickLinksSiteName].Remove(_extraPropertiesQuickLink);
		}

		private void EnableCabCommand(object sender, EventArgs e)
		{
			if (_workItem == null)
			{
				return;
			}

			_workItem.Commands["Exit"].Status = CommandStatus.Enabled;
		}

		private void DisableCabCommand(object sender, EventArgs e)
		{
			_workItem.Commands["Exit"].Status = CommandStatus.Disabled;
		}

		public void OnTearingDown()
		{
		}
	}
}